package com.lorizz.model.impl;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;

import com.lorizz.model.Repository;

public abstract class AbstractRepository<T, ID extends Serializable> extends Object
        implements Repository<T, ID> {
    
    private final Class<T> persistentClass;
    private EntityManager entityManager;
    
    public Class<?> getPersistentClass() {
        return persistentClass;
    }
    
    @SuppressWarnings("unchecked")
    public AbstractRepository() {
        this.persistentClass = (Class<T>) ((ParameterizedType) getClass()
                .getGenericSuperclass()).getActualTypeArguments()[0];
    }
    
    public void setEntityManager(EntityManager entityManager) {
        this.entityManager = entityManager;
    }
    
    public EntityManager getEntityManager() {
        return entityManager;
    }

    @SuppressWarnings("unchecked")
	@Override
    public T load(ID id) {
        return (T) entityManager.find(getPersistentClass(), id);
    }

    @SuppressWarnings("unchecked")
	@Override
    public List<T> findAll() {
        CriteriaBuilder cb = entityManager.getCriteriaBuilder();
        CriteriaQuery<T> cq = (CriteriaQuery<T>) cb.createQuery(getPersistentClass());
        cq.from(getPersistentClass());
        return entityManager.createQuery(cq).getResultList();
    }

    @Override
    public T persist(T entity) {
        entityManager.persist(entity);
        return entity;
    }

    @Override
    public void remove(T entity) {
        entityManager.remove(entity);
    }

}
